from app.database.postgre import SessionDep, col
from app.database.models import Account, App, FirewallRule
from app.models import responses
from app.models.common import FirewallRuleIdJSON, AppIdJSON
from app.models.firewall_rules import (AppFirewallRuleListParams, CreateFirewallRuleJSON, EnableFirewallRuleJSON,
                                       BatchDeleteAppRulesJSON)


async def get_firewall_rules_list(
        account: Account,
        query_params: AppFirewallRuleListParams,
        session: SessionDep
):
    # 构建查询参数
    app_id = query_params.app_id
    page = query_params.page
    page_size = query_params.page_size
    rule_type = query_params.rule_type
    rule_match = query_params.rule_match
    remark = query_params.remark
    is_enabled = query_params.is_enabled

    # 获取查询的应用
    app = session.get(App, query_params.app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 创建筛选条件
    query = session.query(FirewallRule).filter(FirewallRule.app_id == app_id).order_by(col(FirewallRule.id).desc())

    if rule_type is not None:
        query = query.filter(FirewallRule.rule_type == rule_type)

    if rule_match:
        query = query.filter(col(FirewallRule.rule_match).like(f"%{rule_match}%"))

    if remark:
        query = query.filter(col(FirewallRule.remark).like(f"%{remark}%"))

    if is_enabled is not None:
        query = query.filter(FirewallRule.is_enabled == is_enabled)

    # 获取筛选后的总数
    total_count = query.count()
    total_pages = (total_count + page_size - 1) // page_size

    # 对筛选后的数据进行分页
    offset = (page - 1) * page_size
    paginated_query = query.offset(offset).limit(page_size)
    paginated_rules = paginated_query.all()

    return responses.SuccessResponse(
        data={
            'total': total_count,
            'total_pages': total_pages,
            'page': page,
            'page_size': len(paginated_rules),
            'list': [rule.model_dump() for rule in paginated_rules]
        }
    )


async def create_firewall_rule(account: Account, json_data: CreateFirewallRuleJSON, session: SessionDep):
    # 获取当前应用
    app = session.get(App, json_data.app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 构建创建规则的参数
    other_data = json_data.model_dump()
    rule = FirewallRule(**other_data)
    try:
        session.add(rule)
        session.commit()
    except Exception as e:
        session.rollback()
        raise e

    session.refresh(rule)

    return responses.SuccessResponse(msg='规则创建成功', data=rule.model_dump())


async def delete_firewall_rule(account: Account, json_data: FirewallRuleIdJSON, session: SessionDep):
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 获取被删除的规则
    rule = session.get(FirewallRule, json_data.rule_id)
    if not rule or rule.app_id != app_id:
        return responses.Response903()

    session.delete(rule)
    session.commit()

    return responses.SuccessResponse(msg='规则已删除', data=rule.model_dump(include={'id'}))


async def delete_firewall_rules(account: Account, json_data: BatchDeleteAppRulesJSON, session: SessionDep):
    """批量删除选中规则"""
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    rules = session.query(FirewallRule).filter(
        FirewallRule.app_id == app_id, col(FirewallRule.id).in_(json_data.rule_ids)
    ).all()
    if not rules:
        return responses.SuccessResponse(msg='没有找到指定的规则', data={'count': 0, 'ids': []})

    deleted_ids = [rule.id for rule in rules]

    session.query(FirewallRule).filter(
        FirewallRule.app_id == app_id, col(FirewallRule.id).in_(deleted_ids)
    ).delete(synchronize_session=False)

    session.commit()

    return responses.SuccessResponse(msg='选中的规则已删除', data={
        'count': len(deleted_ids),
        'ids': deleted_ids
    })


async def clear_all_firewall_rules(account: Account, json_data: AppIdJSON, session: SessionDep):
    """清空所有防火墙规则"""
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 获取该应用的所有版本
    rules = session.query(FirewallRule).filter(FirewallRule.app_id == app_id).all()
    if not rules:
        return responses.SuccessResponse(msg='该应用没有规则', data={'ids': []})

    deleted_ids = [rule.id for rule in rules]

    session.query(FirewallRule).filter(FirewallRule.app_id == app_id).delete(synchronize_session=False)
    session.commit()

    return responses.SuccessResponse(msg='规则已清空', data={
        'ids': deleted_ids
    })


async def enable_firewall_rule(account: Account, json_data: EnableFirewallRuleJSON, session: SessionDep):
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 获取被修改的规则
    rule = session.get(FirewallRule, json_data.rule_id)
    if not rule or rule.app_id != app_id:
        return responses.Response903()

    rule.is_enabled = json_data.is_enabled
    session.commit()
    session.refresh(rule)
    return responses.SuccessResponse(
        msg='规则已启用' if rule.is_enabled else '规则已关闭',
        data=rule.model_dump(include={'id', 'is_enabled'})
    )
